package org.farng.mp3.id3;

import java.util.Iterator;
import java.util.NoSuchElementException;


/**
 * DOCUMENT ME!
 *
 * @author Eric Farng
 * @version $Revision: 1.3 $
 */
public class ID3v1Iterator implements Iterator {
    /** DOCUMENT ME! */
    private static final int TITLE = 1;

    /** DOCUMENT ME! */
    private static final int ARTIST = 2;

    /** DOCUMENT ME! */
    private static final int ALBUM = 3;

    /** DOCUMENT ME! */
    private static final int COMMENT = 4;

    /** DOCUMENT ME! */
    private static final int YEAR = 5;

    /** DOCUMENT ME! */
    private static final int GENRE = 6;

    /** DOCUMENT ME! */
    private static final int TRACK = 7;

    /** DOCUMENT ME! */
    private ID3v1 id3v1tag;

    /** DOCUMENT ME! */
    private int lastIndex = 0;

    /**
     * Creates a new ID3v1Iterator object.
     *
     * @param id3v1tag DOCUMENT ME!
     */
    public ID3v1Iterator(ID3v1 id3v1tag) {
        this.id3v1tag = id3v1tag;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean hasNext() {
        return hasNext(lastIndex);
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Object next() {
        return next(lastIndex);
    }

    /**
     * DOCUMENT ME!
     */
    public void remove() {
        switch (lastIndex) {
            case TITLE:
                id3v1tag.title = "";

            case ARTIST:
                id3v1tag.artist = "";

            case ALBUM:
                id3v1tag.album = "";

            case COMMENT:
                id3v1tag.comment = "";

            case YEAR:
                id3v1tag.year = "";

            case GENRE:
                id3v1tag.genre = -1;

            case TRACK:

                if (id3v1tag instanceof ID3v1_1) {
                    ((ID3v1_1) id3v1tag).track = -1;
                }
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param index DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    private boolean hasNext(int index) {
        switch (index) {
            case TITLE:
                return (id3v1tag.title.length() > 0) || hasNext(index + 1);

            case ARTIST:
                return (id3v1tag.artist.length() > 0) || hasNext(index + 1);

            case ALBUM:
                return (id3v1tag.album.length() > 0) || hasNext(index + 1);

            case COMMENT:
                return (id3v1tag.comment.length() > 0) || hasNext(index + 1);

            case YEAR:
                return (id3v1tag.year.length() > 0) || hasNext(index + 1);

            case GENRE:
                return (id3v1tag.genre >= 0) || hasNext(index + 1);

            case TRACK:

                if (id3v1tag instanceof ID3v1_1) {
                    return (((ID3v1_1) id3v1tag).track >= 0) || hasNext(index + 1);
                }

            default:
                return false;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param index DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     *
     * @throws NoSuchElementException DOCUMENT ME!
     */
    private Object next(int index) {
        switch (lastIndex) {
            case 0:
                return (id3v1tag.title.length() > 0) ? id3v1tag.title : next(index + 1);

            case TITLE:
                return (id3v1tag.artist.length() > 0) ? id3v1tag.artist : next(index + 1);

            case ARTIST:
                return (id3v1tag.album.length() > 0) ? id3v1tag.album : next(index + 1);

            case ALBUM:
                return (id3v1tag.comment.length() > 0) ? id3v1tag.comment : next(index + 1);

            case COMMENT:
                return (id3v1tag.year.length() > 0) ? id3v1tag.year : next(index + 1);

            case YEAR:
                return (id3v1tag.genre >= 0) ? new Byte(id3v1tag.genre) : next(index + 1);

            case GENRE:
                return (id3v1tag instanceof ID3v1_1 && (((ID3v1_1) id3v1tag).track >= 0)) ? new Byte(((ID3v1_1) id3v1tag).track) : null;

            default:
                throw new NoSuchElementException("Iteration has no more elements.");
        }
    }
}